package com.cskt.petproject178.service.impl;

import com.cskt.petproject178.mapper.ReceiverAddressMapper;
import com.cskt.petproject178.mapper.UserMapper;
import com.cskt.petproject178.pojo.entity.User;
import com.cskt.petproject178.pojo.exception.BaseException;
import com.cskt.petproject178.pojo.vo.AddressVO;
import com.cskt.petproject178.pojo.vo.ResultVO;
import com.cskt.petproject178.pojo.vo.StatusEnum;
import com.cskt.petproject178.pojo.vo.UserInfoVO;
import com.cskt.petproject178.service.UserService;
import com.cskt.petproject178.service.third.AliyunSMSService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author 27013
 **/

@Service
public class UserServiceImpl implements UserService {
    private static final Logger log= LoggerFactory.getLogger(UserServiceImpl.class);
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private AliyunSMSService aliyunSMSService;
    @Resource
    private UserMapper userMapper;
    @Resource
    private ReceiverAddressMapper receiverAddressMapper;
    @Resource
    private ObjectMapper objectMapper;
    @Override
    public Boolean sendCode(String phone,Integer codeType) {
        //1.生成验证码
        int validateCode = new Random().nextInt(1000, 1000000);
        //2.存入redis，Key-value键值对：有效期
     String  validateCodeKey="pet:sms:"+phone+":"+codeType;
        stringRedisTemplate.opsForValue().set(validateCodeKey,String.valueOf(validateCode),5, TimeUnit.MINUTES);
        log.info("手机号码为：{}，验证码为：{}",phone,validateCode);
        //3、发送验证码:通过阿里云的短信发送接口
        //组装短信发送模板参数：json格式
        String templateParam = "{\"code\":"+validateCode+"}";
        return  aliyunSMSService.sendSms(phone, templateParam);
    }

    @Override
    public String login(String phone, String sms) {
        //1.验证当前手机号对应的验证码是否正确
        String validateCodeKey="pet:sms:"+phone+":1";
        //从redis中取出对应的验证码
        String validateCode = stringRedisTemplate.opsForValue().get(validateCodeKey);
        if (!StringUtils.hasText(validateCode)) {
            log.warn("手机号{}验证码已过期",phone);
            // 抛出自定义异常，被全局的异常处理器捕获，处理成为统一的响应结果
           throw new BaseException(StatusEnum.FAIL_UMS_SMS_CODE_ERROR);
        }
        if (!sms.equals(validateCode)) {
            log.warn("手机号{}验证码错误",phone);
            throw new BaseException(StatusEnum.FAIL_UMS_SMS_CODE_ERROR);
        }
        //2.验证当前手机号在数据库中是否存在，如果不存在，则新增一条记录
        User user = userMapper.selectByPhone(phone);
        if (ObjectUtils.isEmpty(user)) {
            //用户不存在，做新增操作
            user=new User();
            user.setAccount(phone);
            user.setUserName(phone);
            user.setCreatedTime(LocalDateTime.now());
            user.setUpdatedTime(LocalDateTime.now());
            userMapper.insertSelective(user);
        }
        //3.生成token，并将用户信息存入token，返回token
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        //将当前登录用户存入redis
        String loginUserKey="pet:token:"+token;
        UserInfoVO userInfoVO = new UserInfoVO();
        userInfoVO.setId(user.getId());
        userInfoVO.setUserName(user.getUserName());
        userInfoVO.setAccount(user.getAccount());
        try {
            //用过objectMapper将user对象序列化为json字符串,过期时间为1小时
            stringRedisTemplate.opsForValue().set(loginUserKey,objectMapper.writeValueAsString(userInfoVO),1,TimeUnit.HOURS);
        } catch (JsonProcessingException e) {
            log.error("将用户信息存入redis时发生的异常",e);
            return null;
        }
        return token;
    }

    @Override
    public List<AddressVO> selectAddressVOByUserId(Long userId) {
        return receiverAddressMapper.selectAddressVOByUserId(userId);
    }
}
